/*
 * Copyright 2008 (c) Mirko Bordjoski,
 *			 www.candymandesign.com | 
 *			 candymandesign.blogspot.com.
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

// _______________________________________________________________
// .......................................................Piwik

package org.piwik
{	
	
	import flash.events.EventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.SecurityErrorEvent;
	import flash.net.URLRequest;
	import flash.net.navigateToURL;
	
	import org.piwik.events.PiwikErrorEvent;
	import org.piwik.events.PiwikEvent;
	import org.piwik.logic.Caller;
	import org.piwik.logic.PiwikParser;
	import org.piwik.requests.PiwikRequest;
	

	/**
	* The Piwik class enables to load the data from the Piwik Analitycs. <p />
	* Usage exampe:<p /> 
	* 
	* <listing><code>
	* 
	* import org.piwik.PiwikSetup; 
	* import org.piwik.events.PiwikEvent;
	* import org.piwik.shortcuts.QuickPiwik;
	* 
	* var qp:QuickPiwik = new QuickPiwik();
	* qp.init();
	* qp.getVisits();
	* qp.addEventListener(PiwikEvent.LOADED, loaded);
	*		
	* function loaded(e:PiwikEvent):void
	* {
	* 	trace(e.data);
	* 	trace(e.requestType); 
	* }
	* 
	* </code>
	* </listing>
	*
	* 
	* 
	* Or you can init Piwik using PiwikSetup object instead using init method: <p />
	* <code>
	* import org.piwik.PiwikSetup;
	* 
	* var piwikSetup:PiwikSetup = new PiwikSetup("your_piwik_path", 1, "anonymous");
	* piwik.setup = piwikSetup;
	* 
	* </code>
	* 
	* @see org.piwik.shortcuts.QuickPiwik
	*/	
	public class Piwik extends EventDispatcher
	{				
		/**
		* Enables engine name to be retrieved at runtime or when reviewing a decompiled swf.
		*/
		public static const 		NAME:String 		= 		"--|| PIWIK ||--";
				
		/**
		* Enables Piwik version to be retrieved at runtime or when reviewing a decompiled swf.
		*/
		public static const 		VERSION:String 		= 		"Public Beta 0.2.2 & 0.2.3";
				
		/**
		* Enables API version to be retrieved at runtime or when reviewing a decompiled swf.
		*/
		public static const 		API_VERSION:String 	= 		"Public Beta 1.0.0";
		
		/**
		* Enables version date to be retrieved at runtime or when reviewing a decompiled swf.
		*/
		public static const 		DATE:String 		= 		"May 2008.";
		
		/**
		* Enables copyright information to be retrieved at runtime or when reviewing a decompiled swf.
		*/
		public static const 		AUTHOR:String 		= 		"(c) Mirko Bordjoski - http://candymandesign.blogspot.com";

		

		/**
		* Enables piwik core team information to be retrieved at runtime or when reviewing a decompiled swf.
		*/
		public static const 		PIWIK_CORE_TEAM:String = 	"(c)  Matthieu Aubry - | Julien Rouvière | Johan Mathé | Thierry Scelles";
				
		
		
		/**
		* Returns data as XML. 
		*/
		public static const 		XML:String 			= 		"xml";
		
		/**
		* Returns data as PHP. 
		*/
		public static const 		PHP:String 			= 		"php";
		
		/**
		* Returns data as HTML. 
		*/
		public static const 		HTML:String 		= 		"html";
		
		/**
		* Returns data as RSS. 
		* @note		Works only in table formated fields.
		*/
		public static const 		RSS:String 			= 		"rss";
		
		/**
		* Returns data as JSON. 
		*/
		public static const 		JSON:String 		= 		"json";
		
		/**
		* Download CSV format. 
		* 
		* @note		It's really ugly CSV file. Hope that Piwik team will fix this. :)
		*/
		public static const 		CSV:String 			= 		"csv";
		
		
		
		/**
		* Show or hide busy cursor while loading the data. Default value is <code>true</code>.
		*@note Flex version only.
		*/	
		public var 					showBusyCursor:Boolean 		= 		true;
				
		/**
		* Sets the format of returning data. Default value is 'xml'.
		*/
		public var 					format:String 				= 		Piwik.XML; 

		/**
		* This variable is used only if returning type is php. Default value is <code>true</code>.
		*/
		public var 					prettyDisplay:Boolean 		= 		true; 			

		/**
		* PiwikSetup object. 
		* <p /> 
		* @note		PiwikSetup object must be defined before sending any requests.
		* @see		org.piwik.managers.UserManager
		*/	
		public var 					settup:PiwikSetup 			= 		null;
		

	
		/**
		 * @private 
	 	*/
		private var 				_urlFull:String;
		
		/**
		 * @private 
	 	*/
		private var 				lastResult:Object;
		
		
		
		
		
		
		/**
		* 
		* Constructor.
		* <p />
		* 
		* The Piwik class loads the data from the Piwik Analitycs. 
		*/		
		public function Piwik(){}			
		
		/**
		* Sets the PiwikSetup object. 
		* <p /> 
		* @note		PiwikSetup object must be defined before sending any requests.
		* 
		* @param	$baseURL			URL of Piwik Analytics page.
		* @param	$siteID				ID of the site.
		* @param	$authToken			Token_auth - uniq for every user.
		* 
		* @see		org.piwik.managers.UserManager
		* 
		*/	
		public function init($baseURL:String = "http://piwik.org/demo/", $siteID:uint = 1, $authToken:String = "anonymous"):void 
		{
			settup = new PiwikSetup($baseURL, $siteID, $authToken);
		}
		
		
				
		/**
		* Sends request to Piwik Analytics. If format value is 'csv', 
		* it will download CSV file from the Piwik.
		*
		* @param	$request				The PiwikRequest object - type of request.
		*
		* @see 		org.piwik.formats.PiwikFormats 
		* @see 		org.piwik.requests.PiwikRequest
		* @see 		org.piwik.events.PiwikEvent
		*/			
		public function makeCall($request:PiwikRequest):void
		{
			if(settup != null)
			{
				setURL($request);
				switch(format)
				{
					case(Piwik.CSV):
					navigateToURL(new URLRequest(_urlFull));
					break;
				
					default:
					Caller.makeCall(_urlFull, $request.requestType, loaded, onIOError, onSecError, true, showBusyCursor);
					break;				
				}	
			}
			else
			{
				dispatchEvent(new PiwikErrorEvent(PiwikErrorEvent.INIT_ERROR,false,false));
			}		
		}			
				
		
		/**
		* Returns last loaded result.
		*/	
		public function getLastResult():Object
		{
			return lastResult;
		}
				
		/**
		* Returns last called url.
		*/	
		public function getLastUrl():String
		{
			return _urlFull;
		}		
				
		/**
		* Returns Piwik Object as a String.
		*/
		override public function toString():String
		{
			var returner:String;
			returner = "API Name: " + Piwik.NAME + "\n";
			returner = "Piwik version: " + Piwik.VERSION + "\n";
			returner += "API version: " + Piwik.API_VERSION + "\n";
			returner += "Date: " + Piwik.DATE + "\n";
			returner += "Author: " + Piwik.AUTHOR + "\n";
			returner += "Piwik core team: " + Piwik.PIWIK_CORE_TEAM + "\n";
			
			return returner;
		}
		
		
		
		/**
		* @private
		*/
		protected function setURL($request:PiwikRequest):void
		{
			_urlFull = settup.getURL(); 
			_urlFull += PiwikRequest.MODULE_METHOD; //PiwikMethods.MODULE_METHOD;
			_urlFull += $request.moduleMethod;
			_urlFull += PiwikRequest.SITE_ID; //PiwikMethods.SITE_ID;
			_urlFull += settup.getSiteID();
			_urlFull += PiwikRequest.PERIOD; //PiwikMethods.PERIOD;
			_urlFull += $request.period;
			_urlFull += PiwikRequest.DATE; //PiwikMethods.DATE;
			_urlFull += $request.date;
			_urlFull += PiwikRequest.FORMAT_RETURN; //PiwikMethods.FORMAT_RETURN;
			_urlFull += format;
			_urlFull += PiwikRequest.FILTER; //PiwikMethods.FILTER;
			_urlFull += $request.filter.toString();
			_urlFull += PiwikRequest.TOKEN; //PiwikMethods.TOKEN;
			_urlFull += settup.getAuthToken();
			
			if(format == Piwik.PHP)
			{				
				_urlFull += PiwikRequest.PRETTY_DISPLAY; //PiwikMethods.PRETTY_DISPLAY;
				_urlFull += prettyDisplay.toString();			
			}			
		}
		
		
		/**
		* @private 
		* Dispatche PiwikEvent.
		*/
		private function loaded(d:Object, who:String):void
		{
			var entries:Array = PiwikParser.parse(d,who);
			dispatchEvent(new PiwikEvent(PiwikEvent.LOADED, false, false, d, who,entries));			
			lastResult = d;
		}
		
		
		
		
		
		
		/**
		* @private 
		* Dispatche PiwikEvent.
		*/
		private function onIOError(message:String):void
		{
			dispatchEvent(new IOErrorEvent(IOErrorEvent.IO_ERROR, false, false, "Piwik can not load the data. Check your Piwik settings."));
			//dispatchEvent(new PiwikEvent(PiwikEvent.IO_ERROR,false,false,null,"undefined",message));
		}
		
		
		
		/**
		* @private 
		* Dispatche PiwikEvent.
		*/
		private function onSecError(message:String):void
		{
			dispatchEvent(new SecurityErrorEvent(SecurityErrorEvent.SECURITY_ERROR, false, false, "SECURITY ERROR."));
			//dispatchEvent(new PiwikEvent(PiwikEvent.SECURITY_ERROR,false,false,null,"undefined",message));
		}
	}
}
		
		